//package cn.icatw.blog.service.impl;
//
//import cn.dev33.satoken.secure.BCrypt;
//import cn.dev33.satoken.stp.StpUtil;
//import cn.hutool.core.lang.Assert;
//import cn.icatw.blog.constant.CommonConst;
//import cn.icatw.blog.constant.MQPrefixConst;
//import cn.icatw.blog.domain.UserAuth;
//import cn.icatw.blog.domain.UserInfo;
//import cn.icatw.blog.domain.UserRole;
//import cn.icatw.blog.dto.EmailDTO;
//import cn.icatw.blog.dto.UserAreaDTO;
//import cn.icatw.blog.dto.UserBackDTO;
//import cn.icatw.blog.dto.UserDetailDTO;
//import cn.icatw.blog.enums.LoginTypeEnum;
//import cn.icatw.blog.enums.RoleEnum;
//import cn.icatw.blog.excetion.BizException;
//import cn.icatw.blog.mapper.UserAuthMapper;
//import cn.icatw.blog.mapper.UserInfoMapper;
//import cn.icatw.blog.mapper.UserRoleMapper;
//import cn.icatw.blog.params.UserConditionParams;
//import cn.icatw.blog.service.BlogInfoService;
//import cn.icatw.blog.service.RedisService;
//import cn.icatw.blog.service.UserAuthService;
//import cn.icatw.blog.utils.AssertUtil;
//import cn.icatw.blog.utils.IpUtil;
//import cn.icatw.blog.utils.PageUtil;
//import cn.icatw.blog.utils.UserUtil;
//import cn.icatw.blog.vo.PageResult;
//import cn.icatw.blog.vo.PasswordVO;
//import cn.icatw.blog.vo.UserVO;
//import com.alibaba.fastjson.JSON;
//import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
//import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
//import com.baomidou.mybatisplus.core.toolkit.IdWorker;
//import com.baomidou.mybatisplus.core.toolkit.StringUtils;
//import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
//import jakarta.annotation.Resource;
//import jakarta.servlet.http.HttpServletRequest;
//import lombok.extern.log4j.Log4j2;
//import org.springframework.amqp.core.Message;
//import org.springframework.amqp.core.MessageProperties;
//import org.springframework.amqp.rabbit.core.RabbitTemplate;
//import org.springframework.scheduling.annotation.Scheduled;
//import org.springframework.stereotype.Service;
//import org.springframework.transaction.annotation.Transactional;
//
//import java.time.LocalDateTime;
//import java.time.ZoneId;
//import java.util.List;
//import java.util.Map;
//import java.util.Objects;
//import java.util.stream.Collectors;
//
//import static cn.icatw.blog.constant.CommonConst.*;
//import static cn.icatw.blog.constant.RedisPrefixConst.*;
//import static cn.icatw.blog.constant.UserInfoConstant.USER_INFO;
//import static cn.icatw.blog.constant.UserInfoConstant.USER_ROLE;
//import static cn.icatw.blog.utils.CommonUtil.checkEmail;
//import static cn.icatw.blog.utils.CommonUtil.getRandomCode;
//import static com.alibaba.fastjson2.util.DateUtils.SHANGHAI_ZONE_ID_NAME;
//
//
///**
// * (UserAuth)表服务实现类
// *
// * @author icatw
// * @since 2024-03-21 11:08:44
// */
//@Service("userAuthService")
//@Log4j2
//public class UserAuthServiceImpl extends ServiceImpl<UserAuthMapper, UserAuth> implements UserAuthService {
//    @Resource
//    HttpServletRequest request;
//    @Resource
//    RabbitTemplate rabbitTemplate;
//    @Resource
//    RedisService redisService;
//    @Resource
//    BlogInfoService blogInfoService;
//    @Resource
//    UserInfoMapper userInfoMapper;
//    @Resource
//    UserRoleMapper userRoleMapper;
//
//    @Override
//    public UserDetailDTO login(String username, String password) {
//        //region 校验密码，登录成功之后修改最后登录时间等等操作
//        UserAuth userAuth = this.baseMapper.getByUsername(username);
//        Assert.isTrue(BCrypt.checkpw(password, userAuth.getPassword()), "账号或密码错误");
//        log.info("{}登录成功", username);
//        updateLoginStatus(userAuth);
//        UserDetailDTO userDetailDTO = UserUtil.getUserDetailDtoByUserId(String.valueOf(userAuth.getId()));
//        StpUtil.login(userAuth.getId());
//        StpUtil.getSession().set(USER_INFO, userDetailDTO);
//        StpUtil.getSession().set(USER_ROLE, userDetailDTO.getRoleList());
//        userDetailDTO.setSaTokenInfo(StpUtil.getTokenInfo());
//        return userDetailDTO;
//        //endregion
//
//    }
//
//    /**
//     * 更新登录状态
//     *
//     * @param userAuth 用户身份验证
//     */
//    private void updateLoginStatus(UserAuth userAuth) {
//        userAuth.setLastLoginTime(LocalDateTime.now(ZoneId.of(SHANGHAI_ZONE_ID_NAME)));
//        String ipAddress = IpUtil.getIpAddress(request);
//        String ipSource = IpUtil.getIpSource(ipAddress);
//        userAuth.setIpAddress(ipAddress);
//        userAuth.setIpSource(ipSource);
//        baseMapper.updateById(userAuth);
//    }
//
//    @Override
//    public PageResult<UserBackDTO> listUserBackDTO(UserConditionParams condition) {
//        // 获取后台用户数量
//        Integer count = baseMapper.countUser(condition);
//        if (count == 0) {
//            return new PageResult<>();
//        }
//        // 获取后台用户列表
//        List<UserBackDTO> userBackDTOList = baseMapper.listUsers(PageUtil.getLimitCurrent(), PageUtil.getSize(), condition);
//        return new PageResult<>(userBackDTOList, count);
//    }
//
//    @Override
//    public void logout() {
//        StpUtil.logout();
//    }
//
//    @Override
//    public void sendCode(String username) {
//        //region 发送验证码
//        // 校验账号是否合法
//        if (!checkEmail(username)) {
//            throw new BizException("请输入正确邮箱");
//        }
//        // 生成六位随机验证码发送
//        String code = getRandomCode();
//        // 发送验证码
//        EmailDTO emailDTO = EmailDTO.builder()
//                .email(username)
//                .subject("验证码")
//                .content("您的验证码为 " + code + " 有效期15分钟，请不要告诉他人哦！")
//                .build();
//        rabbitTemplate.convertAndSend(MQPrefixConst.EMAIL_EXCHANGE, "*", new Message(JSON.toJSONBytes(emailDTO), new MessageProperties()));
//        // 将验证码存入redis，设置过期时间为15分钟
//        redisService.set(USER_CODE_KEY + username, code, CODE_EXPIRE_TIME);
//        //endregion
//    }
//
//    @Override
//    @Transactional(rollbackFor = Exception.class)
//    public void register(UserVO user) {
//        // 校验账号是否合法
//        if (checkUser(user)) {
//            throw new BizException("邮箱已被注册！");
//        }
//        // 新增用户信息
//        UserInfo userInfo = UserInfo.builder()
//                .email(user.getUsername())
//                .nickname(CommonConst.DEFAULT_NICKNAME + IdWorker.getId())
//                .avatar(blogInfoService.getWebsiteConfig().getUserAvatar())
//                .build();
//        userInfoMapper.insert(userInfo);
//        // 绑定用户角色
//        UserRole userRole = UserRole.builder()
//                .userId(userInfo.getId())
//                .roleId(RoleEnum.USER.getRoleId())
//                .build();
//        userRoleMapper.insert(userRole);
//        // 新增用户账号
//        UserAuth userAuth = UserAuth.builder()
//                .userInfoId(userInfo.getId())
//                .username(user.getUsername())
//                .password(BCrypt.hashpw(user.getPassword(), BCrypt.gensalt()))
//                .loginType(LoginTypeEnum.EMAIL.getType())
//                .build();
//        baseMapper.insert(userAuth);
//    }
//
//    @Override
//    public void updatePassword(UserVO user) {
//        // 校验账号是否合法
//        if (!checkUser(user)) {
//            throw new BizException("邮箱尚未注册！");
//        }
//        // 根据用户名修改密码
//        baseMapper.update(new UserAuth(), new LambdaUpdateWrapper<UserAuth>()
//                .set(UserAuth::getPassword, BCrypt.hashpw(user.getPassword(), BCrypt.gensalt()))
//                .eq(UserAuth::getUsername, user.getUsername()));
//    }
//
//    /**
//     * 校验用户数据是否合法
//     *
//     * @param user 用户数据
//     * @return 结果
//     */
//    private Boolean checkUser(UserVO user) {
//        AssertUtil.isTrue(user.getCode().equals(redisService.get(USER_CODE_KEY + user.getUsername())), "验证码错误");
//        //查询用户名是否存在
//        UserAuth userAuth = baseMapper.selectOne(new LambdaQueryWrapper<UserAuth>()
//                .select(UserAuth::getUsername)
//                .eq(UserAuth::getUsername, user.getUsername()));
//        return Objects.nonNull(userAuth);
//    }
//
//    @Transactional(rollbackFor = Exception.class)
//    @Override
//    public void updateAdminPassword(PasswordVO passwordVO) {
//        // 查询旧密码是否正确
//        UserAuth user = baseMapper.selectOne(new LambdaQueryWrapper<UserAuth>()
//                .eq(UserAuth::getId, UserUtil.getCurrentUser().getUserId()));
//        // 正确则修改密码，错误则提示不正确
//        if (Objects.nonNull(user) && BCrypt.checkpw(passwordVO.getOldPassword(), user.getPassword())) {
//            UserAuth userAuth = UserAuth.builder()
//                    .id(UserUtil.getCurrentUser().getUserId())
//                    .password(BCrypt.hashpw(passwordVO.getNewPassword(), BCrypt.gensalt()))
//                    .build();
//            baseMapper.updateById(userAuth);
//        } else {
//            throw new BizException("旧密码不正确");
//        }
//    }
//
//    /**
//     * 统计用户地区
//     */
//    @Scheduled(cron = "0 0 * * * ?")
//    public void statisticalUserArea() {
//        // 统计用户地域分布
//        Map<String, Long> userAreaMap = baseMapper.selectList(new LambdaQueryWrapper<UserAuth>().select(UserAuth::getIpSource))
//                .stream()
//                .map(item -> {
//                    if (StringUtils.isNotBlank(item.getIpSource())) {
//                        return item.getIpSource().substring(0, 2)
//                                .replaceAll(PROVINCE, "")
//                                .replaceAll(CITY, "");
//                    }
//                    return UNKNOWN;
//                })
//                .collect(Collectors.groupingBy(item -> item, Collectors.counting()));
//        // 转换格式
//        List<UserAreaDTO> userAreaList = userAreaMap.entrySet().stream()
//                .map(item -> UserAreaDTO.builder()
//                        .name(item.getKey())
//                        .value(item.getValue())
//                        .build())
//                .collect(Collectors.toList());
//        redisService.set(USER_AREA, JSON.toJSONString(userAreaList));
//    }
//}
//
